package feces.servlet;

import java.io.IOException;
import java.util.List;

import javax.persistence.EntityTransaction;
import javax.persistence.RollbackException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import feces.model.Product;
import feces.model.ProductMinorType;
import feces.model.Storehouse;
import feces.model.StorehouseProduct;
import feces.model.Supplier;
import feces.utility.Utility;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * 商品管理伺服器
 * 
 * @author Bromine0x23
 */
@WebServlet(name="product", urlPatterns={"/api/product"})
@NoArgsConstructor
public class ProductServlet extends RESTfulServlet {
	
	/**
	 * 字典
	 * 
	 * @author Bromine0x23
	 */
	@NoArgsConstructor(access = AccessLevel.PROTECTED)
	public static class Dictionary extends RESTfulServlet.Dictionary {
		
		public static final String NAME = "name";
		
		public static final String MAJOR_ID = "major_id";
		
		public static final String MINOR_ID = "minor_id";
		
		public static final String UNIT = "unit";
		
		public static final String PRICE = "price";
		
		public static final String DISCOUNT = "discount";
		
		public static final String COST = "cost";
		
		public static final String TYPE = "type";
		
		public static final String SUPPLIER_ID = "supplier_id";
		
		public static final String PRODUCTOR = "productor";
		
		public static final String PERIOD = "period";
		
		public static final String RETURNABLE = "returnable";
		
		public static final String CHANGABLE = "changable";
		
		public static final String REMARK = "remark";
	}

	private static final long serialVersionUID = 2870836868320253948L;

	/**
	 * 响应POST请求
	 * 创建商品
	 * 
	 * @return 商品代码
	 */
	@Override
	protected Response<Product> responseCreate(
		HttpServletRequest request,
		HttpServletResponse response
	) throws ServletException, IOException {
		Integer major_id = Utility.toInteger(request.getParameter(Dictionary.MAJOR_ID));
		if (major_id == null) {
			return invalid("无效的商品一级分类", null);
		}
		Integer minor_id = Utility.toInteger(request.getParameter(Dictionary.MINOR_ID));
		if (minor_id == null) {
			return invalid("无效的商品二级分类", null);
		}
		Integer supplier_id = Utility.toInteger(request.getParameter(Dictionary.SUPPLIER_ID));
		if (supplier_id == null) {
			return invalid("无效的供应商", null);
		}
		final Product product = new Product();
		product.setName(request.getParameter(Dictionary.NAME));
		product.setMinorType(find(ProductMinorType.class, minor_id));
		product.setUnit(request.getParameter(Dictionary.UNIT));
		product.setPrice(Utility.toDouble(request.getParameter(Dictionary.PRICE)));
		product.setDiscount(Utility.toDouble(request.getParameter(Dictionary.DISCOUNT)));
		product.setCost(Utility.toDouble(request.getParameter(Dictionary.COST)));
		product.setType(request.getParameter(Dictionary.TYPE));
		product.setSupplier(find(Supplier.class, supplier_id));
		product.setProductor(request.getParameter(Dictionary.PRODUCTOR));
		product.setPeriod(Utility.toDate(request.getParameter(Dictionary.PERIOD)));
		product.setReturnable(Utility.toBoolean(request.getParameter(Dictionary.RETURNABLE)));
		product.setChangable(Utility.toBoolean(request.getParameter(Dictionary.CHANGABLE)));
		product.setRemark(request.getParameter(Dictionary.REMARK));
		if (product.isValid()) {
			boolean result = doTransaction(new Runnable() {

				@Override
				public void run() {
					add(product);
					for (Storehouse storehouse : findAll(Storehouse.class)) {
						StorehouseProduct storehouse_product = new StorehouseProduct();
						storehouse_product.setStorehouseId(storehouse.getId());
						storehouse_product.setProductId(product.getId());
						storehouse_product.setQuantity(0);
						storehouse_product.setCritical(0);
						storehouse_product.setLimit(0);
						add(storehouse_product);
					}
				}

			});
			if (result) {
				return succeed(product);
			}
			return exception(null);
		}
		return failed("数据非法", null);
	}
	
	/**
	 * 响应DELETE请求
	 * 删除商品
	 * 
	 * @return 操作结果
	 */
	@Override
	protected Response<Boolean> responseDelete(
		HttpServletRequest request,
		HttpServletResponse response
	) throws ServletException, IOException {
		String parameter = request.getParameter(Dictionary.ID);
		if (parameter == null) {
			return invalid("未设置主键", false);
		}
		Integer id = Utility.toInteger(parameter);
		if (id == null) {
			return invalid("主键非法", false);
		}
		final Product product = find(Product.class, id);
		boolean result = doTransaction(new Runnable() {

			@Override
			public void run() {
				List<StorehouseProduct> storehouse_products = executeQuery(
					"SELECT p FROM StorehouseProduct p WHERE p.productId = ?1",
					StorehouseProduct.class,
					product.getId()
				);
				for (StorehouseProduct storehouse_product : storehouse_products) {
					remove(storehouse_product);
				}
				remove(product);
			}

		});
		return result ? succeed("删除成功", true) : exception("删除失败，可能有关联数据未清除", false);
	}
	
	/**
	 * 响应GET请求
	 * 获取商品
	 * 
	 * @return 查询结果，可能为空
	 */
	@Override
	protected Response<Product> responseRead(
		HttpServletRequest request,
		HttpServletResponse response
	) throws ServletException, IOException {
		return responseReadBasic(request, Product.class);
	}
	
	/**
	 * 响应PUT请求
	 * 修改商品
	 * 
	 * @return 操作结果
	 */
	@Override
	protected Response<Product> responseUpdate(
		HttpServletRequest request,
		HttpServletResponse response
	) throws ServletException, IOException {
		Integer id = Utility.toInteger(request.getParameter(Dictionary.PK));
		if (id == null) {
			return invalid("主键不能为空", null);
		}
		final Product product = find(Product.class, id);
		String column = request.getParameter(Dictionary.COLUMN);
		String value = request.getParameter(Dictionary.VALUE);
		if (product == null) {
			return invalid("无效的主键", null);
		}
		if (Utility.isEmpty(column)) {
			return invalid("修改域不能为空", null);
		}
		EntityTransaction transaction = getTransaction();
		try {
			transaction.begin();
			switch (column) {
				case Dictionary.NAME: {
					product.setName(value);
					break;
				}
				case Dictionary.MINOR_ID: {
					product.setMinorType(find(ProductMinorType.class, Utility.toInteger(value)));
					break;
				}
				case Dictionary.UNIT: {
					product.setUnit(value);
					break;
				}
				case Dictionary.PRICE: {
					product.setPrice(Utility.toDouble(value));
					break;
				}
				case Dictionary.DISCOUNT: {
					product.setDiscount(Utility.toDouble(value));
					break;
				}
				case Dictionary.COST: {
					product.setCost(Utility.toDouble(value));
					break;
				}
				case Dictionary.TYPE: {
					product.setType(value);
					break;
				}
				case Dictionary.SUPPLIER_ID: {
					product.setSupplier(find(Supplier.class, Utility.toInteger(value)));
					break;
				}
				case Dictionary.PRODUCTOR: {
					product.setProductor(value);
					break;
				}
				case Dictionary.PERIOD: {
					product.setPeriod(Utility.toDate(value));
					break;
				}
				case Dictionary.RETURNABLE: {
					product.setReturnable(Utility.toBoolean(value));
					break;
				}
				case Dictionary.CHANGABLE: {
					product.setReturnable(Utility.toBoolean(value));
					break;
				}
				case Dictionary.REMARK: {
					product.setRemark(value);
					break;
				}
				default:
					return invalid("无效的修改域", null);
			}
			if (product.isValid()) {
				transaction.commit();
				return succeed("修改成功", product);
			}
		} catch (IllegalStateException | RollbackException exception){
			return exception("执行发生异常", null);
		} finally {
			if (transaction.isActive()) {
				transaction.rollback();
			}
		}
		return failed("修改失败", null);
	}
}
